import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 60 * 1000, // request timeout
  headers: { 'content-type': 'application/json;charset=utf-8' }
})
// 记录发送请求次数
let num = 0
// 记录401错误次数
let fourHundred = 0
// 取消401后的请求
window.__axiosPromiseArr = []
/* 记录当前请求是否完成 */
window.currentResq = {
  done: true,
  config: {}
}
// request interceptor 请求拦截
service.interceptors.request.use(
  config => {
    // config.cancelToken = new axios.CancelToken(cancel => {
    //   window.__axiosPromiseArr.push(cancel)
    // })

    num++ // 记录请求数量
    setTimeout(() => {
      // 延时3秒检测请求是否响应完毕
      if (num > 0) {
        store.commit('app/SET_LOADING', true)
      }
    }, 3000)
    // 配置请求头
    if (store.getters.token) {
      config.headers['Authorization'] = 'Bearer ' + getToken()
      window.currentResq = {
        done: false,
        config
      }
    }
    // if (fourHundred) {
    //   window.__axiosPromiseArr.forEach(c => {
    //    typeof cancel === 'function' && c.cancel()
    //   })
    // }
    return config
  },
  error => {
    // do something with request error
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(res => {
  num-- // 请求次数减少
  if (num === 0) {
    // 请求全部完成,结束loading
    store.commit('app/SET_LOADING', false)
  }
  const { config } = window.currentResq
  const { url, method } = res.config
  if (config.url === url && config.method === method) {
    window.currentResq.done = true
  }
  // 未设置状态码则默认成功状态
  const code = res.data.code
  // 获取错误信息
  const msg = errorCode[code] || res.data.message || errorCode['default']
  if (code === 401) {
    if (fourHundred === 0) {
      fourHundred = 1
      MessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
        confirmButtonText: '重新登录',
        cancelButtonText: '取消',
        type: 'warning'
      }
      ).then(() => {
        store.dispatch('user/resetToken')
        location.href = '/login'
        fourHundred = 0
      }).catch(() => { fourHundred = 0 })
    }
    return new Promise(() => {})
  } else if (code === 500) {
    Message({
      message: msg || 'Error',
      type: 'error'
    })
    return Promise.reject(new Error(msg))
  } else {
    return res.data
  }
},
error => {
  num-- // 减少请求次数
  if (num === 0) {
    // 请求全部结束, 取消loading
    store.commit('app/SET_LOADING', false)
  }
  console.log('err' + error) // for debug
  Message({
    message: error.message || 'Error',
    type: 'error',
    duration: 5 * 1000
  })
  return Promise.reject(error)
}
)

export default service
